// miniprogram/pages/capture/capture.js
Page({

  /**
   * 页面的初始数据
   */
  data: {
    localPath: '', // 本地图片路径
    imageWidth: 0, // 图片原宽度
    imageHeight: 0, // 图片原长度
    imageScale: 1, // 图片缩放比例
    viewSize: 300, // 剪切窗口大小
    viewScale: 1, // 移动视图的缩放比例
    x: 0, // 图片位置x
    y: 0, // 图片位置y
    angle: 0, // 旋转角度
    viewStyle: '', // 截图组件样式
    imageStyle: '', // 图片组件样式
  },

  /**
   * 获取截取图片的左上角位置
   * @param {Object} selector 选择器
   */
  getNodePosition (selector) {
    return new Promise((resolve, reject) => {
      const query = wx.createSelectorQuery()
      query.select(selector)
        .boundingClientRect(res => {
          resolve(res)
        }).exec()
    })
  },

  /**
   * 获取页面元素节点
   * @param {Object} selector 选择器
   */
  selectNode (selector) {
    return new Promise((resolve, reject) => {
      const query = wx.createSelectorQuery()
      query.select(selector)
        .fields({ node: true })
        .exec(res => {
          resolve(res[0].node)
        })
    })
  },

  /**
   * 确定
   */
  async bindCapture () {
    const { localPath, viewSize, imageScale, viewScale, imageWidth, imageHeight, angle } = this.data
    const hViewSize = viewSize / 2
    // 图片截取尺寸
    const iSize = viewSize / imageScale / viewScale // 图片截取尺寸
    const iPos = await this.getNodePosition('#captureImage') // 图片元素位置信息
    const wPos = await this.getNodePosition('#captureWindow') // 窗口元素位置信息
    // 图片截取开始位置
    let xTemp = (wPos.left - iPos.left) / imageScale / viewScale
    let yTemp = (wPos.top - iPos.top) / imageScale / viewScale
    let x, y;
    if (angle === 0) {
      x = xTemp
      y = yTemp
    } else if (angle === 90) {
      x = yTemp
      y = imageHeight - xTemp - iSize
    } else if (angle === 180) {
      x = imageWidth - xTemp - iSize
      y = imageHeight - yTemp - iSize
    } else {
      x = imageWidth - yTemp - iSize
      y = xTemp
    }
    // 画布文档
    const canvas = await this.selectNode('#captureCanvas')
    canvas.width = viewSize
    canvas.height = viewSize
    const ctx = canvas.getContext('2d')
    ctx.translate(hViewSize, hViewSize)
    ctx.rotate(angle * Math.PI / 180)
    // 图片文档
    const image = canvas.createImage()
    image.src = localPath
    image.onload = () => {
      // 截图图片
      ctx.drawImage(image, x, y, iSize, iSize, -hViewSize, -hViewSize, viewSize, viewSize)
      setTimeout(() => {
        wx.canvasToTempFilePath({
          x: 0,
          y: 0,
          width: viewSize,
          height: viewSize,
          destWidth: viewSize,
          destHeight: viewSize,
          canvas,
          success(res) {
            const pages = getCurrentPages()
            const last = pages[pages.length - 2]
            if (last) {
              last.setData({ 'formData.image': res.tempFilePath })
              last.cacheData()
            }
            wx.navigateBack()
          }
        })
      }, 0)
    }
  },

  /**
   * 取消
   */
  bindCancel () {
    wx.navigateBack()
  },

  /**
   * 旋转图片
   */
  bindRotate () {
    const angle = (this.data.angle + 90) % 360;
    this.data.angle = angle
    this.updateView()
  },

  /**
   * 重新选择图片
   */
  bindChooseImage () {
    const _this = this;
    return new Promise((resolve, reject) => {
      wx.chooseImage({
        count: 1,
        sizeType: ['compressed'],
        success: function success(res) {
          const path = res.tempFilePaths[0]
          if (path) {
            _this.data.imageScale = 1
            _this.data.viewScale = 1
            _this.data.angle = 0
            _this.updateImage(path)
          }
        },
        fail: function fail(_fail) {
          
        }
      })
    })
  },

  /**
   * 缩放
   */
  bindScale (e) {
    this.data.viewScale = e.detail.scale
  },

  /**
   * 更新图片位置
   */
  updateView () {
    const { imageWidth, imageHeight, viewSize, angle } = this.data
    let imageScale, 
      scaleWidth,
      scaleHeight,
      viewWidth,
      viewHeight,
      x = 0,
      y = 0;
    if (imageWidth <= imageHeight) {
      imageScale = viewSize / imageWidth
      scaleWidth = viewSize
      scaleHeight = imageHeight * imageScale
      if (angle === 0 || angle === 180) {
        viewWidth = scaleWidth
        viewHeight = scaleHeight
        y = - (scaleHeight - viewSize) / 2
      } else {
        viewWidth = scaleHeight
        viewHeight = scaleWidth
        x = - (scaleHeight - viewSize) / 2
      }
    } else {
      imageScale = viewSize / imageHeight
      scaleWidth = imageWidth * imageScale
      scaleHeight = viewSize
      if (angle === 0 || angle === 180) {
        viewWidth = scaleWidth
        viewHeight = scaleHeight
        x = - (scaleWidth - viewSize) / 2
      } else {
        viewWidth = scaleHeight
        viewHeight = scaleWidth
        y = - (scaleWidth - viewSize) / 2
      }
    }
    this.data.imageScale = imageScale
    const viewStyle = `width:${viewWidth}px;height:${viewHeight}px;`
    const imageStyle = `width:${scaleWidth}px;height:${scaleHeight}px;transform:rotate(${angle}deg);`
      + `left:calc(50% - ${scaleWidth/2}px);top:calc(50% - ${scaleHeight/2}px);`
    this.setData({ x, y, viewStyle, imageStyle })
  },

  /**
   * 获取图片尺寸信息
   * @param {String} path 本地图片路径
   */
  getImageInfo (path) {
    return new Promise((resolve, reject) => {
      wx.getImageInfo({
        src: path,
        success(res) {
          resolve(res)
        }, fail(err) {
          resolve(null)
        }
      })
    })
  },

  /**
   * 更新图片
   * @param {String} path 本地图片路径
   */
  async updateImage (path) {
    const imageInfo = await this.getImageInfo(path)
    if (imageInfo) {
      const { width, height } = imageInfo
      this.data.imageWidth = width
      this.data.imageHeight = height
      this.setData({ localPath: path })
      this.updateView()
    }
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    const path = options.path
    this.updateImage(path)
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {

  }
})